package ds.factcom.view.ui.invoice;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import ds.factcom.controller.invoice.InvoiceController;
import ds.factcom.exception.EmptyListProductException;
import ds.factcom.exception.EmptyStringException;
import ds.factcom.exception.NotDefinedClientException;
import ds.factcom.exception.NotExistDomainException;
import ds.factcom.model.Message;
import ds.factcom.view.ui.Messages;
import ds.factcom.view.ui.client.SearchClientView;
import ds.factcom.view.ui.item.ItemView;
import ds.factcom.view.ui.product.SearchProductView;

@SuppressWarnings("serial")
public class InvoiceView extends JDialog implements Observer{

	private JPanel infoPanel;
	
	private JPanel clientPanel;
	private JLabel nameClientLabel;
	private JLabel documentTypeClientLabel;
	private JLabel documentNumberClientLabel;
	private JLabel addressClientLabel;
	private JLabel nameClientValueLabel;
	private JLabel documentTypeClientValueLabel;
	private JLabel documentNumberClientValueLabel;
	private JLabel addressClientValueLabel;
	
	private ButtonGroup buttonGroup; 
	private JRadioButton clientInvoiceRB;
	private JRadioButton companyInvoiceRB;
	private JRadioButton vipInvoiceRB;
	private int selected;
	
	private JScrollPane invoiceTablePanel;
	private JTable productTable;
	
	private JPanel buttonPanel;
	private JButton acceptBtn;
	private JButton cancelBtn;
	private JButton addClientBtn;
	private JButton addProductBtn;
	
	private final InvoiceController invoiceController;
	
	public InvoiceView(InvoiceController invoiceController) {
		this.invoiceController = invoiceController;
		this.invoiceController.addObserver(this);
		initGUI();
	}
	
	private void initGUI() {
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setTitle("Facturar");
		setLocation(200, 300);
		setSize(900, 250);
		setResizable(false);
		setModal(true);
		setLayout(new BorderLayout());
		add(getInfoPanel(), BorderLayout.NORTH);
		add(getInvoiceTablePanel(), BorderLayout.CENTER);
		add(getButtonPanel(), BorderLayout.SOUTH);
		validate();
		repaint();
	}

	public void open() {
		setVisible(true);
	}

//****************************** Panel del cliente *******************************************
	private JPanel getClientPanel() {
		if (clientPanel == null) {
			clientPanel = new JPanel(new GridLayout(2,4));
			clientPanel.setSize(700, 100);
			clientPanel.add(getNameClientLabel());
			clientPanel.add(getDocumentTypeClientLabel());
			clientPanel.add(getDocumentNumberClientLabel());
			clientPanel.add(getAddressClientLabel());
			clientPanel.add(getNameClientValueLabel());
			clientPanel.add(getDocumentTypeClientValueLabel());
			clientPanel.add(getDocumentNumberClientValueLabel());
			clientPanel.add(getAddressClientValueLabel());
			invoiceController.cleanClient();
		}
		return clientPanel;
	}

	private JLabel getNameClientLabel() {
		if (nameClientLabel == null) {
			nameClientLabel = new JLabel("Nombre\n ");
		}
		return nameClientLabel;
	}

	private JLabel getDocumentTypeClientLabel() {
		if (documentTypeClientLabel == null) {
			documentTypeClientLabel = new JLabel("Tipo de Documento\n");
		}
		return documentTypeClientLabel;
	}

	private JLabel getDocumentNumberClientLabel() {
		if (documentNumberClientLabel == null) {
			documentNumberClientLabel = new JLabel("Numero de Documento\n");
		}
		return documentNumberClientLabel;
	}

	private JLabel getAddressClientLabel() {
		if (addressClientLabel == null) {
			addressClientLabel = new JLabel("Direccion\n");
		}
		return addressClientLabel;
	} 	

	private JLabel getNameClientValueLabel() {
		if (nameClientValueLabel == null) {
			nameClientValueLabel = new JLabel();
		}
		return nameClientValueLabel;
	}

	private JLabel getDocumentTypeClientValueLabel() {
		if (documentTypeClientValueLabel == null) {
			documentTypeClientValueLabel = new JLabel();
		}
		return documentTypeClientValueLabel;
	}

	private JLabel getDocumentNumberClientValueLabel() {
		if (documentNumberClientValueLabel == null) {
			documentNumberClientValueLabel = new JLabel();
		}
		return documentNumberClientValueLabel;
	}

	private JLabel getAddressClientValueLabel() {
		if (addressClientValueLabel == null) {
			addressClientValueLabel = new JLabel();
		}
		return addressClientValueLabel;
	}

//******************** Panel de INformacion ************************************************
	private JPanel getInfoPanel() {
		if (infoPanel == null) {
			infoPanel = new JPanel(new GridLayout(2,1));
			infoPanel.add(getClientPanel());
			infoPanel.add(getButtonGroup());
		}
		return infoPanel;
	}
//******************** tipo de factura ************************************************

	private JPanel getButtonGroup() {
		JPanel radioPanel = new JPanel();
		if (buttonGroup == null) {
			buttonGroup = new ButtonGroup();
			buttonGroup.add(getClientInvoiceRB());
			buttonGroup.add(getCompanyInvoiceRB());
			buttonGroup.add(getVipInvoiceRB());
			
			radioPanel = new JPanel(new GridLayout(1, 3));
			radioPanel.setSize(700, 100);
	        radioPanel.add(getClientInvoiceRB());
	        radioPanel.add(getCompanyInvoiceRB());
	        radioPanel.add(getVipInvoiceRB());
		}
		return radioPanel;
	}
	private JRadioButton getClientInvoiceRB() {
		if (clientInvoiceRB == null) {
			clientInvoiceRB = new JRadioButton("Factura cliente persona");
			clientInvoiceRB.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e) {
					selected = 1;
				}
			});
		}
		return clientInvoiceRB;
	}
	private JRadioButton getCompanyInvoiceRB() {
		if (companyInvoiceRB == null) {
			companyInvoiceRB = new JRadioButton("Factura cliente compania");
			companyInvoiceRB.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e) {
					selected = 2;
				}
			});
		}
		return companyInvoiceRB;
	}
	private JRadioButton getVipInvoiceRB() {
		if (vipInvoiceRB == null) {
			vipInvoiceRB = new JRadioButton("Facuta VIP");
			vipInvoiceRB.addActionListener(new ActionListener(){
				@Override
				public void actionPerformed(ActionEvent e) {
					selected = 3;
				}
			});
		}
		return vipInvoiceRB;
	}

//******************** tabla de producto ************************************************
	private JScrollPane getInvoiceTablePanel() {
		if (invoiceTablePanel == null) {
			invoiceTablePanel = new JScrollPane(getProductTable());
		}
		return invoiceTablePanel;
	}
	
	private JTable getProductTable() {
		if (productTable == null) {
			productTable = new JTable(invoiceController.getItemTableModel());
		}
		return productTable;
	}
	
//******************** panel botonera ************************************************
	private JPanel getButtonPanel() {
		if (buttonPanel == null) {
			buttonPanel = new JPanel(new GridLayout(1,4));
			buttonPanel.setSize(700, 50);
			buttonPanel.add(getAddClientBtn());
			buttonPanel.add(getAddProductBtn());
			buttonPanel.add(getAcceptBtn());
			buttonPanel.add(getCancelBtn());
		}
		return buttonPanel;
	}

	private JButton getAcceptBtn() {
		if (acceptBtn == null) {
			acceptBtn = new JButton("Aceptar");
			acceptBtn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					try {
						switch (selected) {
							case 1:{
								invoiceController.generateInviocePerson();
								break;
							}
							case 2: {
								invoiceController.generateInvioceCompany();
								break;
							}
							case 3: {
								invoiceController.generateInvioceVip();
								break;
							}
							default: {
								Messages.showErrorMessage(InvoiceView.this, "Debe elegir una forma de facturar");
								break;
							}
						}
						
						//TODO: Cuando se hace clic en ACEPTAR y no se selecciono una forma de pago, da error cuando cuando invoca el metodo getMountAbsoluty(), ya que no esta generado el invoice
						if(invoiceController.getInvoice() != null){
							Messages.showInformationDialog(InvoiceView.this, "Es total facturado es de "+ 
									invoiceController.getInvoice().getMountAbsoluty(), "Informacion de factura");
							InvoiceView.this.dispose();
						}
					
					} catch (EmptyListProductException e1) {
						Messages.showErrorMessage(InvoiceView.this, e1.getMessage());
					} catch (NotDefinedClientException e1) {
						Messages.showErrorMessage(InvoiceView.this, e1.getMessage());
					}
				}
			});
		}
		return acceptBtn;
	}

	private JButton getCancelBtn() {
		if (cancelBtn == null) {
			cancelBtn = new JButton("Cancelar");
			cancelBtn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					clearData();
				}
			});
		}
		return cancelBtn;
	}

	private JButton getAddClientBtn() {
		if (addClientBtn == null) {
			addClientBtn = new JButton("Adherir Cliente");
			addClientBtn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					new SearchClientView(invoiceController).open();
				}
			});
		}
		return addClientBtn;
	}

	private JButton getAddProductBtn() {
		if (addProductBtn == null) {
			addProductBtn = new JButton("Adherir Producto");
			addProductBtn.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					try {
						new SearchProductView(invoiceController).open();
						//TODO:Correccion ISSUE 29. Ver de moverlo a una exception
						if(invoiceController.existProduct() ){
							new ItemView(invoiceController).open();
						}
					} catch (NotExistDomainException e1) {
						Messages.showErrorMessage(InvoiceView.this, e1.getMessage());
						invoiceController.setProduct(null);
					} catch (EmptyStringException e1) {
						Messages.showErrorMessage(InvoiceView.this, e1.getMessage());
						invoiceController.setProduct(null);
					}
				}
			});
		}
		return addProductBtn;
	}

	@Override
	public void update(Observable observable, Object object) {
		if (observable != null) {
			if (object.equals(Message.PRODUCT_ADDED_SUCCESS)) {
				getProductTable().updateUI();
			} else if (object.equals(Message.CLIENT_FOUND)) {
				setLabels();
			}
			repaint();
		}
	}

	private void setLabels() {
		getNameClientValueLabel().setText(invoiceController.getClientName());
		getDocumentTypeClientValueLabel().setText(invoiceController.getClientDocumentType());
		getDocumentNumberClientValueLabel().setText(invoiceController.getClientDocumentNumber());
		getAddressClientValueLabel().setText(invoiceController.getClientAddress());
		this.repaint();
	}

	private void clearData() {
		clearLabels();
		invoiceController.setInvoice(null);
		invoiceController.setProduct(null);
		invoiceController.removeItems();
		getProductTable().updateUI();
		repaint();
	}
	
	@Override
	public void dispose() {
		clearData();
		super.dispose();
	}

	private void clearLabels() {
		getNameClientValueLabel().setText("");
		getDocumentTypeClientValueLabel().setText("");
		getDocumentNumberClientValueLabel().setText("");
		getAddressClientValueLabel().setText("");
	}
}